home *** CD-ROM | disk | FTP | other *** search
Wrap
#include "rb_plugin.h" #include <Movies.h> #include <QuicktimeComponents.h> #include "QTEffect.h" static double playerGetPosition(REALmoviePlayer instance, long param); static void playerSetPosition(REALmoviePlayer instance, long param, double value); static int movieTrackCount(REALobject instance, long param); static REALpicture moviePictureGetter(REALobject instance, long param); static REALpicture moviePosterGetter(REALobject instance, long param); static void moviePosterSetter(REALobject instance, long param, REALpicture value); static REALobject movieTrack(REALobject instance, int index); static REALobject newVideoTrack(REALobject movie, int width, int height, int frameRate); static REALobject newSoundTrack(REALobject movie, int frameRate); static double trackGetDuration(REALobject instance, long param); static unsigned long trackGetEnabled(REALobject instance, long param); static void trackSetEnabled(REALobject instance, long param, unsigned long value); static REALpicture effectSequenceImageGetter(REALobject instance, long param); static REALobject getQTSMPTEEffect(int wipeId); static REALobject getQTCrossFadeEffect(void); static void newQTEffectSequence(REALobject object, REALobject effect, REALpicture pic1, REALpicture pic2, int frames); static REALobject createMovie(REALfolderItem location); static REALobject openAsEditableMovie(REALfolderItem location); static void videoTrackAppendPicture(REALobject track, REALpicture pic); static int videoTrackSelectCompression(REALobject videoTrack); static void trackDestructor(REALobject track, void *garbage); static void videoTrackDestructor(REALobject track, void *garbage); static void soundTrackDestructor(REALobject track, void *garbage); static void qtEffectDestructor(REALobject object, void *crud); static void qtEffectSequenceDestructor(REALobject object, void *crud); static void editableMovieDestructor(REALobject instance, void *garbage); static void soundTrackAppendSound(REALobject track, REALsound snd); static int soundTrackSelectCompression(REALobject soundTrack); static double moviePositionGetter(REALobject instance, long param); static void moviePositionSetter(REALobject instance, long param, double value); static double movieDurationGetter(REALobject instance, long param); static int movieEOFGetter(REALobject instance, long param); static int movieTimeScaleGetter(REALobject instance, long param); static void movieTimeScaleSetter(REALobject instance, long param, int value); static int movieTimeValueGetter(REALobject instance, long param); static void movieTimeValueSetter(REALobject instance, long param, int value); static int movieTimeDurationGetter(REALobject instance, long param); static int movieDataSize(REALobject instance, long start, long duration); static int trackDataSize(REALobject instance, long start, long duration); static REALobject movieUserDataGetter(REALobject instance, long param); static int userDataGetCount(REALobject instance, REALstring udType); static int userDataGetUserData(REALobject instance, REALstring udType, int index, REALstring *pvalue); static void userDataAddUserData(REALobject instance, REALstring udType, REALstring value); static void userDataRemoveUserData(REALobject instance, REALstring udType, int index); static int userDataAlternateUserDataGetter(REALobject instance, REALstring udType, int index, REALstring *pvalue, int region); static void userDataAlternateUserDataSetter(REALobject instance, REALstring udType, int index, REALstring value, int region); static int trackTrackOffsetGetter(REALobject instance, long param); static void trackTrackOffsetSetter(REALobject instance, long param, int value); static int trackTimeScaleGetter(REALobject instance, long param); static void trackTimeScaleSetter(REALobject instance, long param, int value); static int trackTimeDurationGetter(REALobject instance, long param); static int trackIDGetter(REALobject instance, long param); static void trackFirstSample(REALobject track); static void trackNextSample(REALobject track); static void trackFirstSync(REALobject track); static void trackNextSync(REALobject track); static REALstring trackMediaType(REALobject track, long param); static double soundFormatRateGetter(REALobject instance, long param); static void soundFormatRateSetter(REALobject instance, long param, double value); static int soundFormatSampleSizeGetter(REALobject instance, long param); static void soundFormatSampleSizeSetter(REALobject instance, long param, int value); static int soundFormatChannelCountGetter(REALobject instance, long param); static void soundFormatChannelCountSetter(REALobject instance, long param, int value); static REALstring soundFormatCompressionGetter(REALobject instance, long param); static void soundFormatCompressionSetter(REALobject instance, long param, REALstring value); static int soundFormatSelectSettings(REALobject instance); static void soundFormatConstructor(REALobject instance, double rate, int sampleSize, int channelCount, REALstring compression); static REALobject getSoundConverter(REALobject inputFormat, REALobject outputFormat); static REALobject soundSampleFormatGetter(REALsound instance, long param); static REALstring soundSamplesGetter(REALsound instance, long param); static int soundFormatSamplesPerPacket(REALobject instance, long param); static int soundFormatBytesPerSample(REALobject instance, long param); static int soundFormatBytesPerFrame(REALobject instance, long param); static int soundFormatBytesPerPacket(REALobject instance, long param); static REALobject getQTGraphicsExporter(REALstring format); static void graphicsExporterDestructor(REALobject instance, long dummy); static int graphicsExporterRequestSettings(REALobject instance); static int graphicsExporterHasSettingsDialogGetter(REALobject instance, long param); static REALstring graphicsExporterDefaultExtensionGetter(REALobject instance, long param); static REALstring graphicsExporterSettingsDescriptionGetter(REALobject instance, long param); static int graphicsExporterSavePicture(REALobject instance, REALfolderItem location, REALpicture image); static int graphicsExporterDesiredTargetDataSizeGetter(REALobject instance, long param); static void graphicsExporterDesiredTargetDataSizeSetter(REALobject instance, long param, int value); static int graphicsExporterCompressionQualityGetter(REALobject instance, long param); static void graphicsExporterCompressionQualitySetter(REALobject instance, long param, int value); static REALstring graphicsExporterOutputFileTypeGetter(REALobject instance, long param); static void graphicsExporterOutputFileTypeSetter(REALobject instance, long param, REALstring value); static REALstring graphicsExporterOutputFileCreatorGetter(REALobject instance, long param); static void graphicsExporterOutputFileCreatorSetter(REALobject instance, long param, REALstring value); static Boolean gQuicktime21Installed, gQuicktime30Installed; REALproperty playerProperties[1] = { { nil, "Position", "Double", 0, (REALproc) playerGetPosition, (REALproc) playerSetPosition }, }; REALproperty movieProperties[] = { { nil, "TrackCount", "Integer", 0, (REALproc) movieTrackCount }, { nil, "Position", "Double", 0, (REALproc) moviePositionGetter, (REALproc) moviePositionSetter }, { nil, "Duration", "Double", 0, (REALproc) movieDurationGetter }, { nil, "EOF", "Boolean", 0, (REALproc) movieEOFGetter }, { nil, "Picture", "Picture", 0, (REALproc) moviePictureGetter }, { nil, "Poster", "Picture", 0, (REALproc) moviePosterGetter }, { nil, "UserData", "QTUserData", 0, (REALproc) movieUserDataGetter }, { nil, "TimeScale", "Integer", 0, (REALproc) movieTimeScaleGetter, (REALproc) movieTimeScaleSetter }, { nil, "TimeValue", "Integer", 0, (REALproc) movieTimeValueGetter, (REALproc) movieTimeValueSetter }, { nil, "TimeDuration", "Integer", 0, (REALproc) movieTimeDurationGetter }, }; REALproperty soundProperties[] = { { nil, "SampleFormat", "SoundFormat", 0, (REALproc) soundSampleFormatGetter }, { nil, "Samples", "String", 0, (REALproc) soundSamplesGetter }, }; REALmethodDefinition movieMethods[] = { { (REALproc) movieTrack, REALnoImplementation, "Track(index as integer) As QTTrack"}, { (REALproc) newVideoTrack, REALnoImplementation, "NewVideoTrack(width as integer, height as integer, timeScale as integer) As QTVideoTrack" }, // { (REALproc) newSoundTrack, REALnoImplementation, "NewSoundTrack(timeScale as integer) As QTSoundTrack" }, { (REALproc) movieDataSize, REALnoImplementation, "DataSize(startTime as integer, durationTime As Integer) As Integer" }, }; REALmethodDefinition userDataMethods[] = { { (REALproc) userDataGetCount, REALnoImplementation, "UserDataCount(udType As string) As Integer" }, { (REALproc) userDataGetUserData, REALnoImplementation, "GetUserData(udType As string, index As Integer, ByRef value As string) As Boolean" }, { (REALproc) userDataAddUserData, REALnoImplementation, "AddUserData(udType As string, value As string)" }, { (REALproc) userDataRemoveUserData, REALnoImplementation, "RemoveUserData(udType As string, index As Integer)" }, { (REALproc) userDataAlternateUserDataGetter, REALnoImplementation, "GetUserDataText(udType As string, index As Integer, ByRef value As string, region As Integer) As Boolean" }, { (REALproc) userDataAlternateUserDataSetter, REALnoImplementation, "SetUserDataText(udType As string, index As Integer, value As string, region As Integer)" }, }; REALproperty trackProperties[] = { { nil, "Duration", "Double", 0, (REALproc) trackGetDuration }, { nil, "Enabled", "Boolean", 0, (REALproc) trackGetEnabled, (REALproc) trackSetEnabled }, { nil, "MediaType", "String", 0, (REALproc) trackMediaType }, { nil, "TrackOffset", "Integer", 0, (REALproc) trackTrackOffsetGetter, (REALproc) trackTrackOffsetSetter }, { nil, "TimeScale", "Integer", 0, (REALproc) trackTimeScaleGetter, (REALproc) trackTimeScaleSetter }, { nil, "TimeDuration", "Integer", 0, (REALproc) trackTimeDurationGetter }, { nil, "TrackID", "Integer", 0, (REALproc) trackIDGetter }, }; REALproperty effectSequenceProperties[] = { { nil, "Image", "Picture", 0, (REALproc) effectSequenceImageGetter }, { nil, "Frame", "Integer", 0, REALstandardGetter, REALstandardSetter, FieldOffset(EffectSequenceData, currentFrame) }, }; REALproperty soundFormatProperties[] = { { nil, "Rate", "Double", 0, (REALproc) soundFormatRateGetter, (REALproc) soundFormatRateSetter }, { nil, "SampleSize", "Integer", 0, (REALproc) soundFormatSampleSizeGetter, (REALproc) soundFormatSampleSizeSetter }, { nil, "ChannelCount", "Integer", 0, (REALproc) soundFormatChannelCountGetter, (REALproc) soundFormatChannelCountSetter }, { nil, "Compression", "String", 0, (REALproc) soundFormatCompressionGetter, (REALproc) soundFormatCompressionSetter }, { nil, "SamplesPerPacket", "Integer", 0, (REALproc) soundFormatSamplesPerPacket }, { nil, "BytesPerSample", "Integer", 0, (REALproc) soundFormatBytesPerSample }, { nil, "BytesPerFrame", "Integer", 0, (REALproc) soundFormatBytesPerFrame }, { nil, "BytesPerPacket", "Integer", 0, (REALproc) soundFormatBytesPerPacket }, }; REALmethodDefinition soundFormatMethods[] = { { (REALproc) soundFormatSelectSettings, REALnoImplementation, "SelectSettings As Boolean"}, { (REALproc) soundFormatConstructor, REALnoImplementation, "SoundFormat(rate As Double, SampleSize As Integer, ChannelCount As Integer, compression As String)"}, }; REALmethodDefinition GetQTGraphicsExporterMethod = { (REALproc) getQTGraphicsExporter, REALnoImplementation, "GetQTGraphicsExporter(format as string) As QTGraphicsExporter" }; REALmethodDefinition GetQTSMPTEEffectMethod = { (REALproc) getQTSMPTEEffect, REALnoImplementation, "GetQTSMPTEEffect(Id as integer) As QTEffect" }; REALmethodDefinition GetQTCrossFadeEffectMethod = { (REALproc) getQTCrossFadeEffect, REALnoImplementation, "GetQTCrossFadeEffect As QTEffect" }; REALmethodDefinition GetSoundConverterMethod = { (REALproc) getSoundConverter, REALnoImplementation, "GetSoundConverter(inputFormat As SoundFormat, outputFormat As SoundFormat) As SoundConverter" }; REALmethodDefinition effectSequenceMethods[1] = { { (REALproc) newQTEffectSequence, REALnoImplementation, "QTEffectSequence(effect as QTEffect, image1 as Picture, image2 as Picture, frames as integer)" }, }; REALmethodDefinition folderItemMethods[2] = { { (REALproc) createMovie, REALnoImplementation, "CreateMovie As EditableMovie" }, { (REALproc) openAsEditableMovie, REALnoImplementation, "OpenEditableMovie As EditableMovie" }, }; REALproperty graphicsExporterProperties[] = { { nil, "HasSettingsDialog", "Boolean", 0, (REALproc) graphicsExporterHasSettingsDialogGetter }, { nil, "DefaultExtension", "String", 0, (REALproc) graphicsExporterDefaultExtensionGetter }, { nil, "SettingsDescription", "String", 0, (REALproc) graphicsExporterSettingsDescriptionGetter }, { nil, "DesiredTargetDataSize", "Integer", 0, (REALproc) graphicsExporterDesiredTargetDataSizeGetter, (REALproc) graphicsExporterDesiredTargetDataSizeSetter }, { nil, "CompressionQuality", "Integer", 0, (REALproc) graphicsExporterCompressionQualityGetter, (REALproc) graphicsExporterCompressionQualitySetter }, { nil, "OutputFileType", "String", 0, (REALproc) graphicsExporterOutputFileTypeGetter, (REALproc) graphicsExporterOutputFileTypeSetter }, { nil, "OutputFileCreator", "String", 0, (REALproc) graphicsExporterOutputFileCreatorGetter, (REALproc) graphicsExporterOutputFileCreatorSetter }, }; REALmethodDefinition graphicsExporterMethods[2] = { { (REALproc) graphicsExporterRequestSettings, REALnoImplementation, "RequestSettings As Boolean" }, { (REALproc) graphicsExporterSavePicture, REALnoImplementation, "SavePicture(location As FolderItem, image As Picture) As Boolean" }, }; REALmethodDefinition trackMethods[] = { { (REALproc) trackFirstSample, REALnoImplementation, "FindFirstSample" }, { (REALproc) trackNextSample, REALnoImplementation, "FindNextSample" }, { (REALproc) trackFirstSync, REALnoImplementation, "FindFirstKeyFrame" }, { (REALproc) trackNextSync, REALnoImplementation, "FindNextKeyFrame" }, { (REALproc) trackDataSize, REALnoImplementation, "DataSize(startTime as integer, durationTime As Integer) As Integer" }, }; REALmethodDefinition videoTrackMethods[] = { { (REALproc) videoTrackAppendPicture, REALnoImplementation, "AppendPicture(pic As Picture)"}, { (REALproc) videoTrackSelectCompression, REALnoImplementation, "SelectCompressionSettings As Boolean" }, }; REALmethodDefinition soundConverterMethods[] = { { (REALproc) videoTrackAppendPicture, REALnoImplementation, "Convert(samples As String) As String"}, }; /* REALmethodDefinition soundTrackMethods[] = { { (REALproc) soundTrackAppendSound, REALnoImplementation, "AppendSound(snd As Sound)"}, { (REALproc) soundTrackSelectCompression, REALnoImplementation, "SelectCompressionSettings As Boolean" }, }; */ struct EditableMovieData { Movie aMovie; short resRefNum, resId; Boolean bDirty, bNew; TimeValue currentTime; }; struct QTUserDataData { UserData data; }; struct QTGraphicsExporterData { GraphicsExportComponent component; }; REALclassDefinition playerExtension = { kCurrentREALControlVersion, "MoviePlayer", nil, 0, 0, nil, nil, playerProperties, 1, nil, 0, nil, 0, }; REALclassDefinition editableMovieClass = { kCurrentREALControlVersion, "EditableMovie", nil, sizeof(EditableMovieData), 0, nil, (REALproc) editableMovieDestructor, movieProperties, sizeof(movieProperties) / sizeof(REALproperty), movieMethods, sizeof(movieMethods) / sizeof(REALmethodDefinition), nil, 0, }; REALclassDefinition qtUserDataClass = { kCurrentREALControlVersion, "QTUserData", nil, sizeof(QTUserDataData), 0, nil, nil, nil, 0, userDataMethods, sizeof(userDataMethods) / sizeof(REALmethodDefinition), nil, 0, }; REALclassDefinition folderItemExtension = { kCurrentREALControlVersion, "FolderItem", nil, 0, 0, nil, nil, nil, 0, folderItemMethods, sizeof(folderItemMethods) / sizeof(REALmethodDefinition), nil, 0, }; REALclassDefinition qtGraphicsExporterClass = { kCurrentREALControlVersion, "QTGraphicsExporter", nil, sizeof(QTGraphicsExporterData), 0, nil, (REALproc) graphicsExporterDestructor, graphicsExporterProperties, sizeof(graphicsExporterProperties) / sizeof(REALproperty), graphicsExporterMethods, sizeof(graphicsExporterMethods) / sizeof(REALmethodDefinition), nil, 0, }; struct TrackData { Track theTrack; REALobject movie; }; struct VideoTrackData { Boolean bEdits; TimeValue oldDuration; Fixed frameRate; Boolean bCodecSelected; short codecDepth; CodecQ codecQuality; CodecQ temporalQuality; CodecType cType; CompressorComponent codec; int keyFrameRate; ComponentInstance standardCompressor; Boolean bCompressorPrepared; long maxSize; Handle bits; GWorldPtr compressionPage; ImageSequence seq; ImageDescription **imageDescriptionH; Boolean bFirstFrame; }; /* struct SoundTrackData { Boolean bEdits; TimeValue oldDuration; UnsignedFixed rate; short sSize, cCount; OSType compType; }; */ REALclassDefinition trackClass = { kCurrentREALControlVersion, "QTTrack", nil, sizeof(TrackData), 0, nil, (REALproc) trackDestructor, trackProperties, sizeof(trackProperties) / sizeof(REALproperty), trackMethods, sizeof(trackMethods) / sizeof(REALmethodDefinition), nil, 0, }; REALclassDefinition videoTrackClass = { kCurrentREALControlVersion, "QTVideoTrack", "QTTrack", sizeof(VideoTrackData), 0, nil, (REALproc) videoTrackDestructor, nil, 0, videoTrackMethods, sizeof(videoTrackMethods) / sizeof(REALmethodDefinition), nil, 0, }; struct SoundFormatData { UnsignedFixed rate; short sSize, cCount; OSType compType; }; REALclassDefinition soundExtension = { kCurrentREALControlVersion, "Sound", nil, 0, 0, nil, nil, soundProperties, sizeof(soundProperties) / sizeof(REALproperty), nil, 0, nil, 0, }; REALclassDefinition soundFormatClass = { kCurrentREALControlVersion, "SoundFormat", nil, sizeof(SoundFormatData), 0, nil, nil, soundFormatProperties, sizeof(soundFormatProperties) / sizeof(REALproperty), soundFormatMethods, sizeof(soundFormatMethods) / sizeof(REALmethodDefinition), nil, 0, }; struct SoundConverterData { SoundConverter sc; CompressionInfo ici, oci; unsigned long maxInputFrames, inputBytes, outputBytes; }; REALclassDefinition soundConverterClass = { kCurrentREALControlVersion, "SoundConverter", nil, sizeof(SoundConverterData), 0, nil, nil, nil, 0, soundConverterMethods, sizeof(soundConverterMethods) / sizeof(REALmethodDefinition), nil, 0, }; /* REALclassDefinition soundTrackClass = { kCurrentREALControlVersion, "QTSoundTrack", "QTTrack", sizeof(SoundTrackData), 0, nil, nil, nil, 0, soundTrackMethods, sizeof(soundTrackMethods) / sizeof(REALmethodDefinition), nil, 0, }; */ REALclassDefinition qteffectClass = { kCurrentREALControlVersion, "QTEffect", nil, sizeof(EffectData), 0, nil, (REALproc) qtEffectDestructor, nil, 0, nil, 0, nil, 0 }; REALclassDefinition qteffectSequenceClass = { kCurrentREALControlVersion, "QTEffectSequence", nil, sizeof(EffectSequenceData), 0, nil, (REALproc) qtEffectSequenceDestructor, effectSequenceProperties, sizeof(effectSequenceProperties) / sizeof(REALproperty), effectSequenceMethods, sizeof(effectSequenceMethods) / sizeof(REALmethodDefinition), nil, 0 }; static double playerGetPosition(REALmoviePlayer instance, long param) { TimeScale scale; float f; scale = 1000; f = MCGetCurrentTime(REALgetMoviePlayerController(instance), &scale); f = f / scale; return f; } static void playerSetPosition(REALmoviePlayer instance, long param, double value) { TimeRecord timeSpec; Movie movie; MovieController ctl = REALgetMoviePlayerController(instance); if (!ctl) return; movie = MCGetMovie(ctl); if (!movie) return; if (value < 0.0) value = 0.0; timeSpec.scale = GetMovieTimeScale(movie); value = value * timeSpec.scale; timeSpec.value.lo = value; timeSpec.value.hi = 0; timeSpec.base = GetMovieTimeBase(movie); MCDoAction(ctl, mcActionGoToTime, &timeSpec); } static int movieTrackCount(REALobject instance, long param) { ClassData(editableMovieClass, instance, EditableMovieData, data); return GetMovieTrackCount(data->aMovie); } static REALobject movieTrack(REALobject instance, int index) { ClassData(editableMovieClass, instance, EditableMovieData, mdata); Track t = GetMovieIndTrack(mdata->aMovie, index); REALobject rv; if (!t) return nil; rv = REALnewInstance("QTTrack"); if (rv) { ClassData(trackClass, rv, TrackData, data); data->theTrack = t; data->movie = instance; REALLockObject(data->movie); } return rv; } static double trackGetDuration(REALobject instance, long param) { ClassData(trackClass, instance, TrackData, data); double v = GetTrackDuration(data->theTrack); v = v / GetMovieTimeScale(GetTrackMovie(data->theTrack)); return v; } static unsigned long trackGetEnabled(REALobject instance, long param) { ClassData(trackClass, instance, TrackData, data); if (GetTrackEnabled(data->theTrack)) return 1; else return 0; } static void trackSetEnabled(REALobject instance, long param, unsigned long value) { ClassData(trackClass, instance, TrackData, data); SetTrackEnabled(data->theTrack, value != 0); } static REALpicture effectSequenceImageGetter(REALobject instance, long param) { ClassData(qteffectSequenceClass, instance, EffectSequenceData, data); if (data->lastFrame != data->currentFrame) { BuildEffectSequenceFrame(data, data->currentFrame); data->lastFrame = data->currentFrame; } REALLockObject((REALobject) data->destPicture); return data->destPicture; } static REALobject getQTSMPTEEffect(int wipeId) { REALobject rv; if (!gQuicktime30Installed) return nil; if (!REALenterMovies()) return nil; rv = REALnewInstance("QTEffect"); if (rv) { ClassData(qteffectClass, rv, EffectData, data); BuildSMPTEEffect(data, wipeId); } return rv; } static REALobject getQTCrossFadeEffect(void) { REALobject rv; if (!gQuicktime30Installed) return nil; if (!REALenterMovies()) return nil; rv = REALnewInstance("QTEffect"); if (rv) { ClassData(qteffectClass, rv, EffectData, data); BuildCrossFadeEffect(data); } return rv; } static void newQTEffectSequence(REALobject object, REALobject effect, REALpicture pic1, REALpicture pic2, int frames) { if (!gQuicktime30Installed) return; if (!REALenterMovies()) return; if (effect) { ClassData(qteffectSequenceClass, object, EffectSequenceData, data); ClassData(qteffectClass, effect, EffectData, effectData); if (effectData->theEffectType) BuildEffectSquence(data, effectData, pic1, pic2, frames); } } static void qtEffectDestructor(REALobject object, void *crud) { ClassData(qteffectClass, object, EffectData, effectData); if (effectData->fEffectDescription) QTDisposeAtomContainer(effectData->fEffectDescription); } static void qtEffectSequenceDestructor(REALobject object, void *crud) { ClassData(qteffectSequenceClass, object, EffectSequenceData, data); if (data->fEffectSequenceID != 0L) CDSequenceEnd(data->fEffectSequenceID); if (data->fEffectDescription) QTDisposeAtomContainer(data->fEffectDescription); if (data->pic1) { REALUnlockPictureDescription(data->pic1); REALUnlockObject((REALobject) data->pic1); } else if (data->fGW1) DisposeGWorld(data->fGW1); if (data->pic2) { REALUnlockPictureDescription(data->pic2); REALUnlockObject((REALobject) data->pic2); } else if (data->fGW2) DisposeGWorld(data->fGW2); if (data->destPicture) REALUnlockObject((REALobject) data->destPicture); if (data->fSampleDescription) DisposeHandle((Handle) data->fSampleDescription); } static REALobject createMovie(REALfolderItem location) { FSSpec spec; short resRefNum; Movie aMovie; REALobject newMovie; if (!REALenterMovies()) return nil; if (!REALFSSpecFromFolderItem(&spec, location)) return nil; if (noErr != CreateMovieFile(&spec, 'TVOD', 0, createMovieFileDeleteCurFile | newMovieActive, &resRefNum, &aMovie)) return nil; newMovie = REALnewInstance("editableMovie"); ClassData(editableMovieClass, newMovie, EditableMovieData, data); data->aMovie = aMovie; data->resRefNum = resRefNum; data->bDirty = true; data->bNew = true; return newMovie; } static REALobject openAsEditableMovie(REALfolderItem location) { FSSpec spec; short resRefNum, movieResID; Movie aMovie; REALobject newMovie; OSErr err; movieResID = 0; resRefNum = 0; if (!REALenterMovies()) return nil; if (!REALFSSpecFromFolderItem(&spec, location)) return nil; if (noErr != OpenMovieFile(&spec, &resRefNum, fsRdPerm)) return nil; err = NewMovieFromFile(&aMovie, resRefNum, &movieResID, nil, newMovieActive, nil); if (noErr != err) return nil; newMovie = REALnewInstance("editableMovie"); ClassData(editableMovieClass, newMovie, EditableMovieData, data); data->aMovie = aMovie; data->resRefNum = resRefNum; data->resId = movieResID; data->bDirty = true; data->bNew = false; return newMovie; } static void editableMovieDestructor(REALobject instance, void *garbage) { ClassData(editableMovieClass, instance, EditableMovieData, data); short resId = 0; if (data->bNew) AddMovieResource(data->aMovie, data->resRefNum, &resId, nil); else if (data->bDirty) UpdateMovieResource(data->aMovie, data->resRefNum, data->resId, nil); DisposeMovie(data->aMovie); if (data->resRefNum) CloseMovieFile(data->resRefNum); } static double moviePositionGetter(REALobject instance, long param) { ClassData(editableMovieClass, instance, EditableMovieData, data); double v = data->currentTime; v /= GetMovieTimeScale(data->aMovie); return v; } static double movieDurationGetter(REALobject instance, long param) { ClassData(editableMovieClass, instance, EditableMovieData, data); double v = GetMovieDuration(data->aMovie) / GetMovieTimeScale(data->aMovie); return v; } static int movieEOFGetter(REALobject instance, long param) { ClassData(editableMovieClass, instance, EditableMovieData, data); if (data->currentTime >= GetMovieDuration(data->aMovie)) return 1; return 0; } static void moviePositionSetter(REALobject instance, long param, double value) { ClassData(editableMovieClass, instance, EditableMovieData, data); long v = value * GetMovieTimeScale(data->aMovie); if (v < 0) v = 0; else if (v > GetMovieDuration(data->aMovie)) v = GetMovieDuration(data->aMovie); data->currentTime = v; } static void trackFirstSample(REALobject track) { ClassData(trackClass, track, TrackData, trackData); ClassData(editableMovieClass, trackData->movie, EditableMovieData, movieData); TimeValue theTime = GetMovieDuration(movieData->aMovie); GetTrackNextInterestingTime(trackData->theTrack, nextTimeMediaSample + nextTimeEdgeOK, 0, fixed1, &theTime, nil); if (noErr != GetMoviesError()) movieData->currentTime = GetMovieDuration(movieData->aMovie); else movieData->currentTime = theTime; } static void trackNextSample(REALobject track) { ClassData(trackClass, track, TrackData, trackData); ClassData(editableMovieClass, trackData->movie, EditableMovieData, movieData); TimeValue theTime = GetMovieDuration(movieData->aMovie); if (gQuicktime21Installed) GetTrackNextInterestingTime(trackData->theTrack, nextTimeStep, movieData->currentTime, fixed1, &theTime, nil); else GetTrackNextInterestingTime(trackData->theTrack, nextTimeMediaSample, movieData->currentTime, fixed1, &theTime, nil); if (noErr != GetMoviesError()) movieData->currentTime = GetMovieDuration(movieData->aMovie); else movieData->currentTime = theTime; } static void trackFirstSync(REALobject track) { ClassData(trackClass, track, TrackData, trackData); ClassData(editableMovieClass, trackData->movie, EditableMovieData, movieData); TimeValue theTime = GetMovieDuration(movieData->aMovie); GetTrackNextInterestingTime(trackData->theTrack, nextTimeSyncSample + nextTimeEdgeOK, 0, fixed1, &theTime, nil); if (noErr != GetMoviesError()) movieData->currentTime = GetMovieDuration(movieData->aMovie); else movieData->currentTime = theTime; } static void trackNextSync(REALobject track) { ClassData(trackClass, track, TrackData, trackData); ClassData(editableMovieClass, trackData->movie, EditableMovieData, movieData); TimeValue theTime = GetMovieDuration(movieData->aMovie); GetTrackNextInterestingTime(trackData->theTrack, nextTimeSyncSample, movieData->currentTime, fixed1, &theTime, nil); if (noErr != GetMoviesError()) movieData->currentTime = GetMovieDuration(movieData->aMovie); else movieData->currentTime = theTime; } static REALstring trackMediaType(REALobject track, long param) { ClassData(trackClass, track, TrackData, trackData); OSType mediaType; GetMediaHandlerDescription(GetTrackMedia(trackData->theTrack), &mediaType, nil, nil); return REALBuildString((Ptr) &mediaType, 4); } static REALobject newVideoTrack(REALobject instance, int width, int height, int frameRate) { ClassData(editableMovieClass, instance, EditableMovieData, data); Track aTrack = NewMovieTrack(data->aMovie, (long)width << 16, (long)height << 16, 0); REALobject rv; if (!aTrack) return nil; Media aMedia = NewTrackMedia(aTrack, VideoMediaType, frameRate, nil, (OSType)nil); if (!aMedia) return nil; BeginMediaEdits(aMedia); rv = REALnewInstance("QTVideoTrack"); if (rv) { ClassData(trackClass, rv, TrackData, trackData); ClassData(videoTrackClass, rv, VideoTrackData, data); trackData->theTrack = aTrack; trackData->movie = instance; REALLockObject(trackData->movie); data->bEdits = true; } return rv; } static void videoTrackAppendPicture(REALobject track, REALpicture pic) { ClassData(trackClass, track, TrackData, trackData); ClassData(videoTrackClass, track, VideoTrackData, data); Rect r; Fixed width, height; long compressedFrameSize; Media trackMedia = GetTrackMedia(trackData->theTrack); CGrafPtr oldPort; GDHandle oldDevice; if (!data->bEdits) { BeginMediaEdits(trackMedia); data->bEdits = true; data->oldDuration = GetMediaDuration(trackMedia); ClassData(editableMovieClass, trackData->movie, EditableMovieData, data); data->bDirty = true; } GetTrackDimensions(trackData->theTrack, &width, &height); SetRect(&r, 0, 0, width >> 16, height >> 16); if (data->standardCompressor) { if (data->bFirstFrame) { SCSpatialSettings ss; SCGetInfo(data->standardCompressor, scSpatialSettingsType, &ss); if (ss.depth == 0) ss.depth = 16; if (noErr != NewGWorld(&data->compressionPage, ss.depth, &r, nil, nil, 0)) NewGWorld(&data->compressionPage, ss.depth, &r, nil, nil, useTempMem); } } else { if (!data->bCodecSelected) { data->codecDepth = 16; data->codecQuality = codecNormalQuality; data->temporalQuality = 0; data->cType = 'raw '; data->codec = anyCodec; data->keyFrameRate = 16; data->bCodecSelected = true; } if (!data->bCompressorPrepared) { if (noErr != NewGWorld(&data->compressionPage, data->codecDepth, &r, nil, nil, 0)) NewGWorld(&data->compressionPage, data->codecDepth, &r, nil, nil, useTempMem); GetMaxCompressionSize(data->compressionPage->portPixMap, &r, data->codecDepth, data->codecQuality, data->cType, data->codec, &data->maxSize); data->bCompressorPrepared = true; data->bits = NewHandle(data->maxSize); data->imageDescriptionH = (ImageDescription **)NewHandle(sizeof(ImageDescription)); data->bFirstFrame = true; data->bCompressorPrepared = true; } } LockPixels(GetGWorldPixMap(data->compressionPage)); GetGWorld(&oldPort, &oldDevice); SetGWorld(data->compressionPage, nil); EraseRect(&r); if (pic) REALDrawPicturePrimitive(pic, &r, false); OSErr result; Handle bits; if (data->standardCompressor) { short notSyncFlag = 0; if (data->bFirstFrame) { SCCompressSequenceBegin(data->standardCompressor, data->compressionPage->portPixMap, &r, &data->imageDescriptionH); data->bFirstFrame = false; } SCCompressSequenceFrame(data->standardCompressor, data->compressionPage->portPixMap, &r, &bits, &compressedFrameSize, ¬SyncFlag); } else { if (data->bFirstFrame) { result = CompressSequenceBegin(&data->seq, data->compressionPage->portPixMap, nil, &r, nil, data->codecDepth, data->cType, data->codec, data->codecQuality, data->temporalQuality, data->keyFrameRate, nil, codecFlagUpdatePreviousComp, data->imageDescriptionH); data->bFirstFrame = false; } HLock(data->bits); Ptr compressBits = StripAddress(*data->bits); result = CompressSequenceFrame(data->seq, data->compressionPage->portPixMap, &r, codecFlagUpdatePreviousComp, compressBits, &compressedFrameSize, nil, nil); HUnlock(data->bits); bits = data->bits; } SetGWorld(oldPort, oldDevice); UnlockPixels(GetGWorldPixMap(data->compressionPage)); result = AddMediaSample(trackMedia, bits, 0L, compressedFrameSize, (TimeValue)1, (SampleDescriptionHandle)data->imageDescriptionH, 1L, 0, nil); } static void shutdownCurrentVideoCompressor(VideoTrackData *data) { if (data->standardCompressor) { if (!data->bFirstFrame) SCCompressSequenceEnd(data->standardCompressor); data->bFirstFrame = true; if (data->compressionPage) { DisposeGWorld(data->compressionPage); data->compressionPage = nil; } } else { if (data->seq) { CDSequenceEnd(data->seq); data->seq = 0; } if (data->bCompressorPrepared) { DisposeHandle((Handle) data->imageDescriptionH); DisposeHandle(data->bits); DisposeGWorld(data->compressionPage); data->bCompressorPrepared = false; } } } static void videoTrackDestructor(REALobject track, void *garbage) { ClassData(videoTrackClass, track, VideoTrackData, data); ClassData(trackClass, track, TrackData, trackData); Media trackMedia = GetTrackMedia(trackData->theTrack); shutdownCurrentVideoCompressor(data); if (data->standardCompressor) CloseComponent(data->standardCompressor); if (data->bEdits) { TimeValue newDuration = GetMediaDuration(trackMedia); if (newDuration > data->oldDuration) InsertMediaIntoTrack(trackData->theTrack, -1, data->oldDuration, newDuration - data->oldDuration, 0x10000); EndMediaEdits(trackMedia); } } /* static void soundTrackDestructor(REALobject track, void *garbage) { ClassData(soundTrackClass, track, SoundTrackData, data); ClassData(trackClass, track, TrackData, trackData); Media trackMedia = GetTrackMedia(trackData->theTrack); if (data->bEdits) { TimeValue newDuration = GetMediaDuration(trackMedia); if (newDuration > data->oldDuration) InsertMediaIntoTrack(trackData->theTrack, -1, data->oldDuration, newDuration - data->oldDuration, 0x10000); EndMediaEdits(trackMedia); } } */ static void trackDestructor(REALobject track, void *garbage) { ClassData(trackClass, track, TrackData, data); REALUnlockObject(data->movie); } static int videoTrackSelectCompression(REALobject videoTrack) { ClassData(videoTrackClass, videoTrack, VideoTrackData, data); shutdownCurrentVideoCompressor(data); if (!data->standardCompressor) data->standardCompressor = OpenDefaultComponent(StandardCompressionType, StandardCompressionSubType); ComponentResult result; if (!data->standardCompressor) return false; result = SCRequestSequenceSettings(data->standardCompressor); if (result < 0 || result == scUserCancelled) { CloseComponent(data->standardCompressor); data->standardCompressor = nil; return false; } data->bFirstFrame = true; return true; } static REALpicture moviePictureGetter(REALobject instance, long param) { ClassData(editableMovieClass, instance, EditableMovieData, data); PicHandle pic; pic = GetMoviePict(data->aMovie, data->currentTime); if (pic) return REALBuildPictureFromPicHandle(pic, true); else return nil; } static REALpicture moviePosterGetter(REALobject instance, long param) { ClassData(editableMovieClass, instance, EditableMovieData, data); PicHandle pic; pic = GetMoviePosterPict(data->aMovie); if (pic) return REALBuildPictureFromPicHandle(pic, true); else return nil; } static REALobject movieUserDataGetter(REALobject instance, long param) { ClassData(editableMovieClass, instance, EditableMovieData, data); REALobject rv = REALnewInstance("QTUserData"); ClassData(qtUserDataClass, rv, QTUserDataData, rvdata); rvdata->data = GetMovieUserData(data->aMovie); return rv; } static int movieTimeScaleGetter(REALobject instance, long param) { ClassData(editableMovieClass, instance, EditableMovieData, data); return GetMovieTimeScale(data->aMovie); } static void movieTimeScaleSetter(REALobject instance, long param, int value) { ClassData(editableMovieClass, instance, EditableMovieData, data); SetMovieTimeScale(data->aMovie, value); } static int movieTimeValueGetter(REALobject instance, long param) { ClassData(editableMovieClass, instance, EditableMovieData, data); return data->currentTime; } static void movieTimeValueSetter(REALobject instance, long param, int value) { ClassData(editableMovieClass, instance, EditableMovieData, data); data->currentTime = value; } static int movieTimeDurationGetter(REALobject instance, long param) { ClassData(editableMovieClass, instance, EditableMovieData, data); return GetMovieDuration(data->aMovie); } static int movieDataSize(REALobject instance, long start, long duration) { ClassData(editableMovieClass, instance, EditableMovieData, data); return GetMovieDataSize(data->aMovie, start, duration); } static int userDataGetCount(REALobject instance, REALstring udType) { ClassData(qtUserDataClass, instance, QTUserDataData, data); return CountUserDataType(data->data, REALstringToOSType(udType)); } static int userDataGetUserData(REALobject instance, REALstring udType, int index, REALstring *pvalue) { int rv = 0; Handle hData = NewHandle(0); ClassData(qtUserDataClass, instance, QTUserDataData, data); if (noErr == GetUserData(data->data, hData, REALstringToOSType(udType), index)) { rv = 1; if (*pvalue) REALUnlockString(*pvalue); HLock(hData); *pvalue = REALBuildString(*hData, GetHandleSize(hData)); } DisposeHandle(hData); return rv; } static void userDataAddUserData(REALobject instance, REALstring udType, REALstring value) { Handle hData = NewHandle(0); ClassData(qtUserDataClass, instance, QTUserDataData, data); SetHandleSize(hData, value->Length()); BlockMoveData(value->CString(), *hData, value->Length()); AddUserData(data->data, hData, REALstringToOSType(udType)); DisposeHandle(hData); } static void userDataRemoveUserData(REALobject instance, REALstring udType, int index) { ClassData(qtUserDataClass, instance, QTUserDataData, data); RemoveUserData(data->data, REALstringToOSType(udType), index); } static int userDataAlternateUserDataGetter(REALobject instance, REALstring udType, int index, REALstring *pvalue, int region) { int rv = 0; Handle hData = NewHandle(0); ClassData(qtUserDataClass, instance, QTUserDataData, data); if (noErr == GetUserDataText(data->data, hData, REALstringToOSType(udType), index, region)) { rv = 1; if (*pvalue) REALUnlockString(*pvalue); HLock(hData); *pvalue = REALBuildString(*hData, GetHandleSize(hData)); } DisposeHandle(hData); return rv; } static void userDataAlternateUserDataSetter(REALobject instance, REALstring udType, int index, REALstring value, int region) { Handle hData = NewHandle(0); ClassData(qtUserDataClass, instance, QTUserDataData, data); SetHandleSize(hData, value->Length()); BlockMoveData(value->CString(), *hData, value->Length()); AddUserDataText(data->data, hData, REALstringToOSType(udType), index, region); DisposeHandle(hData); } static int trackDataSize(REALobject instance, long start, long duration) { ClassData(trackClass, instance, TrackData, data); return GetTrackDataSize(data->theTrack, start, duration); } static int trackTrackOffsetGetter(REALobject instance, long param) { ClassData(trackClass, instance, TrackData, data); return GetTrackOffset(data->theTrack); } static void trackTrackOffsetSetter(REALobject instance, long param, int value) { ClassData(trackClass, instance, TrackData, data); SetTrackOffset(data->theTrack, value); } static int trackTimeScaleGetter(REALobject instance, long param) { ClassData(trackClass, instance, TrackData, data); return GetMediaTimeScale(GetTrackMedia(data->theTrack)); } static void trackTimeScaleSetter(REALobject instance, long param, int value) { ClassData(trackClass, instance, TrackData, data); SetMediaTimeScale(GetTrackMedia(data->theTrack), value); } static int trackTimeDurationGetter(REALobject instance, long param) { ClassData(trackClass, instance, TrackData, data); return GetMediaDuration(GetTrackMedia(data->theTrack)); } static int trackIDGetter(REALobject instance, long param) { ClassData(trackClass, instance, TrackData, data); return GetTrackID(data->theTrack); } /* struct SoundFormatData { UnsignedFixed rate; short sSize, cCount; OSType compType; }; */ static double soundFormatRateGetter(REALobject instance, long param) { ClassData(soundFormatClass, instance, SoundFormatData, data); double v = data->rate; return v / 65536.0; } static void soundFormatRateSetter(REALobject instance, long param, double value) { ClassData(soundFormatClass, instance, SoundFormatData, data); data->rate = value * 65536.0; } static int soundFormatSampleSizeGetter(REALobject instance, long param) { ClassData(soundFormatClass, instance, SoundFormatData, data); return data->sSize; } static void soundFormatSampleSizeSetter(REALobject instance, long param, int value) { ClassData(soundFormatClass, instance, SoundFormatData, data); data->sSize = value; } static int soundFormatChannelCountGetter(REALobject instance, long param) { ClassData(soundFormatClass, instance, SoundFormatData, data); return data->cCount; } static void soundFormatChannelCountSetter(REALobject instance, long param, int value) { ClassData(soundFormatClass, instance, SoundFormatData, data); data->cCount = value; } static REALstring soundFormatCompressionGetter(REALobject instance, long param) { ClassData(soundFormatClass, instance, SoundFormatData, data); return REALBuildString((Ptr) &data->compType, 4); } static void soundFormatCompressionSetter(REALobject instance, long param, REALstring value) { ClassData(soundFormatClass, instance, SoundFormatData, data); data->compType = REALstringToOSType(value); } static int soundFormatSamplesPerPacket(REALobject instance, long param) { ClassData(soundFormatClass, instance, SoundFormatData, data); CompressionInfo ici; GetCompressionInfo(fixedCompression, data->compType, data->cCount, data->sSize, &ici); return ici.samplesPerPacket; } static int soundFormatBytesPerSample(REALobject instance, long param) { ClassData(soundFormatClass, instance, SoundFormatData, data); CompressionInfo ici; GetCompressionInfo(fixedCompression, data->compType, data->cCount, data->sSize, &ici); return ici.bytesPerSample; } static int soundFormatBytesPerFrame(REALobject instance, long param) { ClassData(soundFormatClass, instance, SoundFormatData, data); CompressionInfo ici; GetCompressionInfo(fixedCompression, data->compType, data->cCount, data->sSize, &ici); return ici.bytesPerFrame; } static int soundFormatBytesPerPacket(REALobject instance, long param) { ClassData(soundFormatClass, instance, SoundFormatData, data); CompressionInfo ici; GetCompressionInfo(fixedCompression, data->compType, data->cCount, data->sSize, &ici); return ici.bytesPerPacket; } static int soundFormatSelectSettings(REALobject instance) { ClassData(soundFormatClass, instance, SoundFormatData, data); ComponentInstance ci; OSErr err; int rv; REALSelectGraphics(nil); ci = OpenDefaultComponent(StandardCompressionType, StandardCompressionSubTypeSound); SCSetInfo(ci, scSoundSampleRateType, &data->rate); SCSetInfo(ci, scSoundSampleSizeType, &data->sSize); SCSetInfo(ci, scSoundChannelCountType, &data->cCount); SCSetInfo(ci, scSoundCompressionType, &data->compType); err = SCRequestImageSettings(ci); if (err < 0 || err == scUserCancelled) { rv = 0; } else { SCGetInfo(ci, scSoundSampleRateType, &data->rate); SCGetInfo(ci, scSoundSampleSizeType, &data->sSize); SCGetInfo(ci, scSoundChannelCountType, &data->cCount); SCGetInfo(ci, scSoundCompressionType, &data->compType); rv = 1; } CloseComponent(ci); return rv; } static void soundFormatConstructor(REALobject instance, double rate, int sampleSize, int channelCount, REALstring compression) { ClassData(soundFormatClass, instance, SoundFormatData, data); data->rate = rate * 65536.0; data->sSize = sampleSize; data->cCount = channelCount; data->compType = REALstringToOSType(compression); } static REALobject getSoundConverter(REALobject inputFormat, REALobject outputFormat) { ClassData(soundFormatClass, inputFormat, SoundFormatData, inputData); ClassData(soundFormatClass, outputFormat, SoundFormatData, outputData); SoundComponentData inputInfo, outputInfo; inputInfo.flags = 0; inputInfo.format = inputData->compType; inputInfo.numChannels = inputData->cCount; inputInfo.sampleSize = inputData->sSize; inputInfo.sampleRate = inputData->rate; inputInfo.sampleCount = 0; inputInfo.buffer = 0; inputInfo.reserved = 0; outputInfo.flags = 0; outputInfo.format = outputData->compType; outputInfo.numChannels = outputData->cCount; outputInfo.sampleSize = outputData->sSize; outputInfo.sampleRate = outputData->rate; outputInfo.sampleCount = 0; outputInfo.buffer = 0; outputInfo.reserved = 0; SoundConverter sc; if (noErr != SoundConverterOpen(&inputInfo, &outputInfo, &sc)) return nil; REALobject rv = REALnewInstance("SoundConverter"); ClassData(soundConverterClass, rv, SoundConverterData, data); data->sc = sc; GetCompressionInfo(fixedCompression, inputInfo.format, inputInfo.numChannels, inputInfo.sampleSize, &data->ici); GetCompressionInfo(fixedCompression, outputInfo.format, outputInfo.numChannels, outputInfo.sampleSize, &data->oci); SoundConverterGetBufferSizes(data->sc, 8192, &data->maxInputFrames, &data->inputBytes, &data->outputBytes); return rv; } static REALstring soundConverterConvert(REALobject instance, REALstring inputData) { ClassData(soundConverterClass, instance, SoundConverterData, data); int inputLen, inputOffset, inFrames; Ptr outputBuffer; int dataOffset; unsigned long outFrames, outBytes; int numFrames; Handle hresult; REALstring sResult; numFrames = inputData->Length() / data->ici.bytesPerFrame; outputBuffer = NewPtr(data->outputBytes); hresult = NewHandle(0); SoundConverterBeginConversion(data->sc); inputOffset = 0; while (inputOffset < numFrames) { if ((inputOffset + data->maxInputFrames) > numFrames) inFrames = numFrames - inputOffset; else inFrames = data->maxInputFrames; SoundConverterConvertBuffer(data->sc, inputData->CString() + inputOffset * data->ici.bytesPerFrame, inFrames, outputBuffer, &outFrames, &outBytes); inputOffset += inFrames; PtrAndHand(outputBuffer, hresult, outBytes); } SoundConverterEndConversion(data->sc, outputBuffer, &outFrames, &outBytes); if (outBytes) PtrAndHand(outputBuffer, hresult, outBytes); DisposePtr(outputBuffer); HLock(hresult); sResult = REALBuildString(*hresult, GetHandleSize(hresult)); DisposeHandle(hresult); return sResult; } static REALobject soundSampleFormatGetter(REALsound instance, long param) { REALsoundDescription description; REALLockSoundDescription(instance, &description); if (description.soundType == soundMacintoshSnd) { Handle hsound = (Handle) description.soundData; REALobject instance = nil; Byte handleState; unsigned long numFrames, dataOffset; SoundComponentData inputInfo; handleState = HGetState(hsound); HLock(hsound); if (noErr == ParseSndHeader((SndListHandle) description.soundData, &inputInfo, &numFrames, &dataOffset)) { instance = REALnewInstance("SoundFormat"); ClassData(soundFormatClass, instance, SoundFormatData, data); data->rate = inputInfo.sampleRate; data->sSize = inputInfo.sampleSize; data->cCount = inputInfo.numChannels; data->compType = inputInfo.format; } HSetState(hsound, handleState); return instance; } return nil; } static REALstring soundSamplesGetter(REALsound instance, long param) { REALsoundDescription description; REALLockSoundDescription(instance, &description); if (description.soundType == soundMacintoshSnd) { Handle hsound = (Handle) description.soundData; Byte handleState; unsigned long numFrames, dataOffset; SoundComponentData inputInfo; CompressionInfo ici; REALstring rv = nil; handleState = HGetState(hsound); HLock(hsound); if (noErr == ParseSndHeader((SndListHandle) description.soundData, &inputInfo, &numFrames, &dataOffset)) { GetCompressionInfo(fixedCompression, inputInfo.format, inputInfo.numChannels, inputInfo.sampleSize, &ici); rv = REALBuildString(*hsound + dataOffset, ici.bytesPerFrame * numFrames); } HSetState(hsound, handleState); return rv; } return nil; } /* static REALobject newSoundTrack(REALobject instance, int frameRate) { ClassData(editableMovieClass, instance, EditableMovieData, data); Track aTrack = NewMovieTrack(data->aMovie, 0, 0, kFullVolume); REALobject rv; if (!aTrack) return nil; Media aMedia = NewTrackMedia(aTrack, SoundMediaType, frameRate, nil, 0); if (!aMedia) return nil; BeginMediaEdits(aMedia); rv = REALnewInstance("QTSoundTrack"); if (rv) { ClassData(trackClass, rv, TrackData, trackData); ClassData(soundTrackClass, rv, SoundTrackData, data); trackData->theTrack = aTrack; trackData->movie = instance; REALLockObject(trackData->movie); data->bEdits = true; data->rate = rate22khz; data->sSize = 16; data->cCount = 2; data->compType = kIMACompression; } return rv; } static void soundTrackAppendSound(REALobject instance, REALsound snd) { ClassData(trackClass, instance, TrackData, trackData); ClassData(soundTrackClass, instance, SoundTrackData, data); Media trackMedia = GetTrackMedia(trackData->theTrack); REALsoundDescription description; if (!data->bEdits) { BeginMediaEdits(trackMedia); data->bEdits = true; data->oldDuration = GetMediaDuration(trackMedia); ClassData(editableMovieClass, trackData->movie, EditableMovieData, data); data->bDirty = true; } REALLockSoundDescription(snd, &description); if (description.soundType == soundMacintoshSnd) { SoundComponentData inputInfo, outputInfo; unsigned long numFrames, dataOffset; unsigned long maxInputFrames, inputBytes, outputBytes; CompressionInfo ici, oci; unsigned long inputOffset; Handle hsound = (Handle) description.soundData; Byte handleState; SoundDescriptionHandle sndH; handleState = HGetState(hsound); HLock(hsound); if (noErr == ParseSndHeader((SndListHandle) description.soundData, &inputInfo, &numFrames, &dataOffset)) { // inputInfo now holds input format // determine appropriate multiplier for sample size conversion for sound track time scale // set output format to desired output format outputInfo.flags = 0; outputInfo.format = data->compType; outputInfo.numChannels = data->cCount; outputInfo.sampleSize = data->sSize; outputInfo.sampleRate = data->rate; outputInfo.sampleCount = 0; outputInfo.buffer = 0; outputInfo.reserved = 0; // start the conversion SoundConverter sc; if (noErr == SoundConverterOpen(&inputInfo, &outputInfo, &sc)) { Handle outputBuffer; unsigned long outFrames, outBytes; SoundConverterGetBufferSizes(sc, 8192, &maxInputFrames, &inputBytes, &outputBytes); GetCompressionInfo(fixedCompression, inputInfo.format, inputInfo.numChannels, inputInfo.sampleSize, &ici); GetCompressionInfo(fixedCompression, outputInfo.format, outputInfo.numChannels, outputInfo.sampleSize, &oci); outputBuffer = NewHandle(outputBytes); HLock(outputBuffer); sndH = (SoundDescriptionHandle) NewHandleClear(sizeof(SoundDescription)); HLock((Handle) sndH); (**sndH).descSize = sizeof(SoundDescription); (**sndH).dataFormat = outputInfo.format; (**sndH).numChannels = outputInfo.numChannels; (**sndH).sampleSize = outputInfo.sampleSize; (**sndH).sampleRate = outputInfo.sampleRate; SoundConverterBeginConversion(sc); inputOffset = 0; // loop through the frame sets while (inputOffset < numFrames) { unsigned long inFrames = numFrames - inputOffset; if (inFrames > maxInputFrames) inFrames = maxInputFrames; SoundConverterConvertBuffer(sc, (*hsound) + dataOffset + inputOffset * ici.bytesPerFrame, inFrames, *outputBuffer, &outFrames, &outBytes); AddMediaSample(trackMedia, outputBuffer, 0L, outBytes, (TimeValue)1, (SampleDescriptionHandle)sndH, outBytes / oci.bytesPerPacket * oci.samplesPerPacket, 0, nil); inputOffset += inFrames; } // flush remaining frames SoundConverterEndConversion(sc, *outputBuffer, &outFrames, &outBytes); if (outFrames) AddMediaSample(trackMedia, outputBuffer, 0L, outBytes, (TimeValue)1, (SampleDescriptionHandle)sndH, outBytes / oci.bytesPerPacket * oci.samplesPerPacket, 0, nil); // dispose of buffers DisposeHandle(outputBuffer); DisposeHandle((Handle) sndH); } } HSetState(hsound, handleState); } REALUnlockSoundDescription(snd); } static int soundTrackSelectCompression(REALobject instance) { ClassData(soundTrackClass, instance, SoundTrackData, data); ComponentInstance ci; OSErr err; int rv; REALSelectGraphics(nil); ci = OpenDefaultComponent(StandardCompressionType, StandardCompressionSubTypeSound); SCSetInfo(ci, scSoundSampleRateType, &data->rate); SCSetInfo(ci, scSoundSampleSizeType, &data->sSize); SCSetInfo(ci, scSoundChannelCountType, &data->cCount); SCSetInfo(ci, scSoundCompressionType, &data->compType); err = SCRequestImageSettings(ci); if (err < 0 || err == scUserCancelled) { rv = 0; } else { SCGetInfo(ci, scSoundSampleRateType, &data->rate); SCGetInfo(ci, scSoundSampleSizeType, &data->sSize); SCGetInfo(ci, scSoundChannelCountType, &data->cCount); SCGetInfo(ci, scSoundCompressionType, &data->compType); rv = 1; } CloseComponent(ci); return rv; } */ /* Boolean bCodecSelected; short codecDepth; CodecQ codecQuality; CodecQ temporalQuality; CodecType cType; CompressorComponent codec; int keyFrameRate; Boolean bCompressorPrepared; long maxSize; Handle bits; GWorldPtr compressionPage; ImageSequence seq; ImageDescription **imageDescriptionH; */ /* REALexport pluginExports[] = { { nil, movieGetPosition }, { nil, movieSetPosition }, { nil, trackGetDuration }, { nil, movieTrackCount }, { nil, movieTrack }, { nil, trackGetEnabled }, { nil, trackSetEnabled }, { nil, effectSequenceImageGetter }, { nil, getQTSMPTEEffect }, { nil, newQTEffectSequence }, { nil, qtEffectDestructor }, { nil, qtEffectSequenceDestructor }, { nil, getQTCrossFadeEffect }, { nil, createMovie }, { nil, newVideoTrack }, { nil, videoTrackAppendPicture }, { nil, videoTrackDestructor }, { nil, trackDestructor }, { nil, videoTrackSelectCompression }, }; short pluginExportCode = sizeof(pluginExports) / sizeof(REALexport); */ /* struct QTGraphicsExporterData { GraphicsExportComponent component; }; */ static REALobject getQTGraphicsExporter(REALstring format) { ComponentInstance ci; if (noErr == OpenADefaultComponent(GraphicsExporterComponentType, REALstringToOSType(format), &ci)) { REALobject rv = REALnewInstance("QTGraphicsExporter"); ClassData(qtGraphicsExporterClass, rv, QTGraphicsExporterData, data); data->component = ci; return rv; } else return nil; } static void graphicsExporterDestructor(REALobject instance, long dummy) { ClassData(qtGraphicsExporterClass, instance, QTGraphicsExporterData, data); CloseComponent(data->component); } static int graphicsExporterRequestSettings(REALobject instance) { ClassData(qtGraphicsExporterClass, instance, QTGraphicsExporterData, data); if (noErr == GraphicsExportRequestSettings(data->component, nil, nil)) return 1; return 0; } static int graphicsExporterHasSettingsDialogGetter(REALobject instance, long param) { ClassData(qtGraphicsExporterClass, instance, QTGraphicsExporterData, data); if (CallComponentCanDo(data->component, kGraphicsExportRequestSettingsSelect)) return 1; return 0; } static REALstring graphicsExporterDefaultExtensionGetter(REALobject instance, long param) { ClassData(qtGraphicsExporterClass, instance, QTGraphicsExporterData, data); OSType extension; const char *sz; int i; if (noErr == GraphicsExportGetDefaultFileNameExtension(data->component, &extension)) { sz = (const char *) &extension; for (i = 0; i < 4; i++) if (!sz[i]) break; return REALBuildString(sz, i); } return nil; } static REALstring graphicsExporterSettingsDescriptionGetter(REALobject instance, long param) { return nil; } static int graphicsExporterSavePicture(REALobject instance, REALfolderItem location, REALpicture image) { ClassData(qtGraphicsExporterClass, instance, QTGraphicsExporterData, data); FSSpec spec; REALpictureDescription description; int rv; if (!REALFSSpecFromFolderItem(&spec, location)) return 0; if (noErr != GraphicsExportSetOutputFile(data->component, &spec)) return 0; REALLockPictureDescription(image, &description); rv = 1; if (description.pictureType == pictureMacintoshPICT) { GraphicsExportSetInputPicture(data->component, (PicHandle) description.pictureData); } else if (description.pictureType == pictureMacintoshGWorld) { GraphicsExportSetInputGWorld(data->component, (GWorldPtr) description.pictureData); } else rv = 0; if (rv) { if (noErr != GraphicsExportDoExport(data->component, nil)) rv = 0; } REALUnlockPictureDescription(image); return rv; } static int graphicsExporterDesiredTargetDataSizeGetter(REALobject instance, long param) { ClassData(qtGraphicsExporterClass, instance, QTGraphicsExporterData, data); unsigned long size; if (noErr != GraphicsExportGetTargetDataSize(data->component, &size)) return 0; return size; } static void graphicsExporterDesiredTargetDataSizeSetter(REALobject instance, long param, int value) { ClassData(qtGraphicsExporterClass, instance, QTGraphicsExporterData, data); GraphicsExportSetTargetDataSize(data->component, value); } static int graphicsExporterCompressionQualityGetter(REALobject instance, long param) { ClassData(qtGraphicsExporterClass, instance, QTGraphicsExporterData, data); unsigned long quality; if (noErr != GraphicsExportGetCompressionQuality(data->component, &quality)) return 0; return quality; } static void graphicsExporterCompressionQualitySetter(REALobject instance, long param, int value) { ClassData(qtGraphicsExporterClass, instance, QTGraphicsExporterData, data); GraphicsExportSetCompressionQuality(data->component, value); } static REALstring graphicsExporterOutputFileTypeGetter(REALobject instance, long param) { ClassData(qtGraphicsExporterClass, instance, QTGraphicsExporterData, data); OSType fileType, fileCreator; GraphicsExportGetOutputFileTypeAndCreator(data->component, &fileType, &fileCreator); return REALBuildString((char *) &fileType, 4); } static void graphicsExporterOutputFileTypeSetter(REALobject instance, long param, REALstring value) { ClassData(qtGraphicsExporterClass, instance, QTGraphicsExporterData, data); OSType fileType, fileCreator; GraphicsExportGetOutputFileTypeAndCreator(data->component, &fileType, &fileCreator); GraphicsExportSetOutputFileTypeAndCreator(data->component, REALstringToOSType(value), fileCreator); } static REALstring graphicsExporterOutputFileCreatorGetter(REALobject instance, long param) { ClassData(qtGraphicsExporterClass, instance, QTGraphicsExporterData, data); OSType fileType, fileCreator; GraphicsExportGetOutputFileTypeAndCreator(data->component, &fileType, &fileCreator); return REALBuildString((char *) &fileCreator, 4); } static void graphicsExporterOutputFileCreatorSetter(REALobject instance, long param, REALstring value) { ClassData(qtGraphicsExporterClass, instance, QTGraphicsExporterData, data); OSType fileType, fileCreator; GraphicsExportGetOutputFileTypeAndCreator(data->component, &fileType, &fileCreator); GraphicsExportSetOutputFileTypeAndCreator(data->component, fileType, REALstringToOSType(value)); } void PluginEntry(void) { long result; OSErr error = Gestalt(gestaltQuickTime, &result); if (error == noErr) { if (result >= 0x2100000) gQuicktime21Installed = true; if (result >= 0x3000000) gQuicktime30Installed = true; } REALRegisterClass(&soundFormatClass); REALRegisterClass(&soundConverterClass); REALRegisterClass(&qteffectClass); REALRegisterClass(&qteffectSequenceClass); REALRegisterClass(&qtUserDataClass); REALRegisterClass(&trackClass); REALRegisterClass(&videoTrackClass); REALRegisterClass(&qtGraphicsExporterClass); // REALRegisterClass(&soundTrackClass); REALRegisterClass(&editableMovieClass); REALRegisterClassExtension(&playerExtension); REALRegisterClassExtension(&folderItemExtension); REALRegisterClassExtension(&soundExtension); REALRegisterMethod(&GetQTGraphicsExporterMethod); REALRegisterMethod(&GetQTSMPTEEffectMethod); REALRegisterMethod(&GetQTCrossFadeEffectMethod); }